package com.orange.base.core.config;

import java.io.IOException;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;

@Configuration
@PropertySource(value = "classpath:druid.properties")
public class HibernateConfiguration {

    private static final Log LOGGER = LogFactory.getLog(HibernateConfiguration.class);

    @Value("${spring.datasource.druid.dbType}")
    private String dbType;

    @Value("${spring.hibernate.dialect:#{null}}")
    private String dialect;

    @Value("${spring.hibernate.hbm2ddl.auto}")
    private String auto;

    @Value("${spring.hibernate.default_schema}")
    private String defaultSchema;

    /**
     * 配置hibernate
     * 
     * @param dataSource
     * @return
     */
    @Bean(name = "localSessionFactory")
    @Autowired
    public LocalSessionFactoryBean localSessionFactoryBean(DataSource dataSource) {
        try {
            LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
            sessionFactory.setDataSource(dataSource);
            // hibernate 生成bean扫描路径
            sessionFactory.setPackagesToScan("com.bstek.uflo.model*", "com.orange.**.entity*");
            // 加载hibernate映射文件
            ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
            Resource[] resources = resolver.getResources("classpath*:com/orange/**/entity/*.hbm.xml");
            sessionFactory.setMappingLocations(resources);
            Properties hibernateProperties = new Properties();

            hibernateProperties.setProperty("hibernate.dialect", getHibernateDialect());
            if ("mysql".equalsIgnoreCase(dbType)) {
                hibernateProperties.setProperty("hibernate.show_sql", "false");
            } else {
                hibernateProperties.setProperty("hibernate.show_sql", "true");
            }
            hibernateProperties.setProperty("hibernate.hbm2ddl.auto", auto);
            if ("oracle".equalsIgnoreCase(dbType)) {
                hibernateProperties.setProperty("hibernate.default_schema", defaultSchema);
            }
            sessionFactory.setHibernateProperties(hibernateProperties);
            return sessionFactory;
        } catch (IOException e) {
            LOGGER.error(e);
        }
        return null;
    }

    private String getHibernateDialect() {
        if (dialect != null && !"".equals(dialect)) {
            return dialect;
        } else if ("oracle".equalsIgnoreCase(dbType)) {
            return "org.hibernate.dialect.Oracle10gDialect";
        } else if ("mysql".equalsIgnoreCase(dbType)) {
            return "org.hibernate.dialect.MySQL5InnoDBDialect";
        } else if ("h2".equalsIgnoreCase(dbType)) {
            return "org.hibernate.dialect.H2Dialect";
        } else {
            return dialect;
        }
    }

    /**
     * 事务
     * 
     * @param sessionFactory
     * @return
     */
    @Bean(name = "transactionManager")
    @Autowired
    public HibernateTransactionManager HibernateTransactionManager(LocalSessionFactoryBean localSessionFactory) {
        HibernateTransactionManager transactionManager = new HibernateTransactionManager();
        transactionManager.setSessionFactory(localSessionFactory.getObject());
        return transactionManager;
    }
}
